package com.yx.cloud.network.ble.yx;

import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;

import com.iot.common.utils.LogUtils;
import com.yx.cloud.network.ble.BleDataHandler;
import com.yx.cloud.network.ble.Cmd;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class YxBleDataHandler extends BleDataHandler {

    public YxBleDataHandler(){
        UUID_SERVICE = UUID.fromString("00001910-0000-1000-8000-00805f9b34fb");
        UUID_WRITE_CHARACTERISTIC = UUID.fromString("00002b10-0000-1000-8000-00805f9b34fb");
        UUID_NOTIFY_CHARICTERISTICE = UUID.fromString("00002b10-0000-1000-8000-00805f9b34fb");
    }

    @Override
    public boolean validateService(BluetoothGatt gatt) {
        //get target service from service list
        mTransportService = gatt.getService(UUID_SERVICE);
        if (mTransportService == null) {
            LogUtils.i("validateService fail : service not found");
            return false;
        }

        //get characteristic from service
        mWriteCharacteristic = mTransportService.getCharacteristic(UUID_WRITE_CHARACTERISTIC);
        mNotifyCharacteristic = mTransportService.getCharacteristic(UUID_NOTIFY_CHARICTERISTICE);
        LogUtils.i("validateService mWriteCharacteristic :" + mWriteCharacteristic);
        LogUtils.i("validateService mNotifyCharacteristic :" + mNotifyCharacteristic);
        if (mWriteCharacteristic == null || mNotifyCharacteristic == null) {
            LogUtils.i("validateService fail : writeCharacteristic or notifyCharacteristic  not found");
            return false;
        }

        gatt.requestMtu(127);
        return true;

//            boolean setNotifyResult = mBluetoothGatt.setCharacteristicNotification(mNotifyCharacteristic, true);
//            LogUtils.i("setCharacteristicNotification : " + setNotifyResult);
//            if (!setNotifyResult) {
//                LogUtils.i("validateService fail : enable notification fail,make sure server allow notification");
//                return false;
//            }
//
//            BluetoothGattDescriptor descriptor = mNotifyCharacteristic.getDescriptor(Constants.UUID_NOTIFY_DESCRIPTOR);
//            if (descriptor == null) {
//                LogUtils.i("validateService fail : descriptor not found ");
//                return false;
//            }
//
//            descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
//            boolean registNotify = mBluetoothGatt.writeDescriptor(descriptor);
//            LogUtils.i("writeDescriptor : " + registNotify);
//            return registNotify;
    }

    public List<YxBleDataPacket> packageData(Cmd command) {
        byte cmd = command.getCmd();
        byte[] content = command.getContent();
        if (content == null) {
            //只有命令的空数据包
            List<YxBleDataPacket> dataPacketList = new ArrayList<>();
            dataPacketList.add(sliceCmd((byte) 1, (byte) 1, cmd, null));
            return dataPacketList;
        }

        int remain = content.length;
        int position = 0;
        int currentPackSize;
        byte order = 0;
        byte packageSum = (byte) Math.ceil(content.length * 1f / YxBleDataPacket.REAL_SIZE);

        List<YxBleDataPacket> dataPacketList = new ArrayList<>();
        while (remain > 0) {
            order++;
            if (remain >= YxBleDataPacket.REAL_SIZE) {
                currentPackSize = YxBleDataPacket.REAL_SIZE;
                byte[] pack = new byte[currentPackSize];
                System.arraycopy(content, position, pack, 0, pack.length);
                dataPacketList.add(sliceCmd(order, packageSum, cmd, pack));
            } else {
                currentPackSize = remain;
                byte[] pack = new byte[currentPackSize];
                System.arraycopy(content, position, pack, 0, pack.length);
                dataPacketList.add(sliceCmd(order, packageSum, cmd, pack));
            }

            position += currentPackSize;
            remain -= currentPackSize;

        }
        return dataPacketList;
    }

    private static YxBleDataPacket sliceCmd(byte order, byte packageSum, byte cmd, byte[] raw) {
        byte[] packData = null;
        if (raw != null) {
            packData = new byte[6 + raw.length];
            packData[0] = YxBleDataPacket.HEADER;
            packData[1] = order;
            packData[2] = packageSum;
            packData[3] = (byte) (raw.length + 1);
            packData[4] = cmd;
            System.arraycopy(raw, 0, packData, 5, raw.length);
            packData[4 + raw.length + 1] = getCheckSum(cmd, raw);
        } else {
            packData = new byte[6];
            packData[0] = YxBleDataPacket.HEADER;
            packData[1] = order;
            packData[2] = packageSum;
            packData[3] = 1;
            packData[4] = cmd;
            packData[5] = getCheckSum(cmd, null);
        }


        return new YxBleDataPacket(packData);
    }

    private static byte getCheckSum(byte cmd, byte[] contentSlice) {
        byte sum = cmd;

        if (contentSlice != null) {
            for (int i = 0; i < contentSlice.length; i++) {
                sum += contentSlice[i];
            }
        }

        return sum;
    }


    public boolean unPackageData(Cmd cmd, byte[] packData) {
        boolean isValid = YxBleDataPacket.validateSlicePackage(packData);

        if (!isValid) {
            return false;
        }

        YxBleDataPacket dataPacket = new YxBleDataPacket(packData);
        cmd.addSlicePackage(dataPacket);

        //如果两个命令不同 丢弃前一个指令 重新接收新的指令
        if (cmd.getCmd() != packData[4]) {
            cmd.clear();
        }

        cmd.addSlicePackage(dataPacket);

        cmd.checkComplete();

        return cmd.isComplete();
    }

}
